package pl.prv.polanie.client.widgets;

import java.util.ArrayList;
import java.util.List;

import pl.prv.polanie.client.Planner;
import pl.prv.polanie.client.widgets.util.GUIUtil;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventPreview;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ChangeListenerCollection;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.MouseListenerAdapter;
import com.google.gwt.user.client.ui.PopupListener;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SourcesChangeEvents;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;


public class SelectBox extends Composite implements SourcesChangeEvents {
	
	private static final String STYLE__SELECT_BOX = "plan-SelectBox";
	private static final String STYLE__SELECT_BOX_HEADER = "plan-SelectBox-header";
	private static final String STYLE__SELECT_BOX_FOOTER = "plan-SelectBox-footer";

	private static final String STYLE__SELECT_BOX_ITEMSLIST = "plan-SelectBox-itemsList";
	private static final String STYLE__SELECT_BOX_ITEMSLIST_WRAPPER = "plan-SelectBox-itemsListWrapper";
	
	
	
	
	private static final String STYLE_ITEMSLIST_SELECTED = "selected";
	private static final String STYLE_ITEMSLIST_HOVER = "hover";
	
	private static final String STYLE__SELECT_BOX_RESIZE_HANDLER = "plan-SelectBox-ResizeHandler";
	private static final String STYLE__SELECT_BOX_DROPDOWN_ICON = "plan-SelectBox-DropDownIcon";
	private static final String STYLE__SELECT_BOX_DROPDOWN_ICON_DISABLED = "plan-SelectBox-DropDownIcon-disabled";
	
	private static final String STYLE__SELECT_BOX_BORDER = "plan-SelectBox-Border";
	private static final String STYLE__SELECT_BOX_BORDERN = "plan-SelectBox-BorderN";
	private static final String STYLE__SELECT_BOX_BORDERS = "plan-SelectBox-BorderS";
	private static final String STYLE__SELECT_BOX_BORDERE = "plan-SelectBox-BorderE";
	private static final String STYLE__SELECT_BOX_BORDERW = "plan-SelectBox-BorderW";
	
	private static final String STYLE__SELECT_BOX_DROPDOWN_ICON_ON_FOCUS = "plan-SelectBox-DropDownIcon-onFocus";
	
	private static final String STYLE_ONFOCUS = "plan-labelUTextBox-onFocus";
	private static final String STYLE_ONLOSTFOCUS = "plan-labelUTextBox-onLostFocus";
	
	private static final String STYLE__ITEMS_SP = "itemsSP";
	
	private AbsolutePanel mainAP = new AbsolutePanel();
	
	private AbsolutePanel itemsAP = new AbsolutePanel();
	
//	private HTML headerHTML = new HTML();
	private HTML footerHTML = new HTML();
	private HTML resizeHandlerHTML = null;
	private HTML dropDownIconHTML = null;
	
	private ScrollPanel itemsSP = new ScrollPanel();
	
	private VerticalPanel itemsVP = new VerticalPanel();
	
	private HTML borderN = new HTML();
	private HTML borderS = new HTML();
	private HTML borderE = new HTML();
	private HTML borderW = new HTML();
	
	private EventPreview draggingEP = null;
//	private EventPreview activeEP = null;
	
	//przechowuje szerokosc kontrolki podczas rozpoczynania zmiany rozmiaru 
	private int startResizingWidth = 0;
	private int startResizingHeight = 0;
	
	private int startResizingMouseX = 0;
	private int startResizingMouseY = 0;
	
	private int selectedItemindex = 0;
	
	int onClickPassedThrough = 0;
	
	private int widgetWidth = 200;
	private int widgetHeight = 100;
	
	private int headerHeight = 16;
	
	private int itemHeight = 16;
	
	
	private boolean itemsPanelDisplayed = false;
	
	private String noItemsLabel = "no items"; 
	
	
	//indicates if items panel dragging at the moment
//	private boolean draggingInProgress = false;
	
//	private int cursorOutOfItemsPanelWhileDragging = 0;
//	private int cursorOutOfItemsPanelWhileDraggingCopy = 0;
	
	private boolean itemsPanelDisplayedAtLeastOnce = false;
	
	private boolean itemsPanelWidthSet = false;
	
	private TextBox textBox = new TextBox();

	List<String> items = new ArrayList<String>();
	List<String> values = new ArrayList<String>();
	
	private int visibleItemsCount = 10;
	
	private ClickListener dropDownIconClickListener = null;
	
	
	private ChangeListenerCollection changeListeners = null;
	
	
	
	
	public SelectBox() {


		
//		setupHeaderHTML();
		setupFooterHTML();
		setupResizeHandler();
		setupDropDownIcon();
		setupBordersHTML();
		setupItemsVP();
		setupItemsSP();
		setupMainAP();
		
		mainAP.addStyleName("mainAP");
		mainAP.add(textBox, 0, 0);
		mainAP.add(dropDownIconHTML);
		
		//TEXTBOX
		Planner.disableSelection(textBox.getElement());
		
		textBox.setReadOnly(true);
		textBox.addStyleName(STYLE__SELECT_BOX);
		textBox.addStyleName(STYLE_ONLOSTFOCUS);
		
		textBox.addFocusListener(new FocusListener() {
			public void onFocus(Widget sender) {
				setViewOnFocus();
			}
			public void onLostFocus(Widget sender) {
				setViewOnLostFocus();
			}
		});
		

		
		//podmienic na odbieranie clickow tylko
		
//		DOM.setEventListener(textBox.getElement(), new EventListener(){
//			public void onBrowserEvent(Event event) {
//				turnOnItemsPanel();
//				DOM.eventCancelBubble(event, true);
//			}
//		});
		
		
		textBox.addClickListener(new ClickListener(){
			public void onClick(Widget sender) {
				if (itemsPanelDisplayed) {
					//chowamy
					turnOffItemsPanel();
				} else {
					//pokazujemy
					turnOnItemsPanel();
					setViewOnFocus();
				}
			}
		});
		
		DOM.setStyleAttribute(textBox.getElement(), "cursor", "pointer");
		textBox.setHeight(20+"px");
		
		

		
		
		
		initWidget(mainAP);

		
//		addExampleValues();
		//initWidget(mainAP);
		
	}
	
	private void addExampleValues() {
		for (int i = 0; i < 20; i++) {
			addItem("tekst widoczny " + i, "ukryty no."+i);
		}
	}
	
	private void setupFooterHTML() {
		footerHTML.setStyleName(STYLE__SELECT_BOX_FOOTER);
		//footerHTML.setWidth(widgetWidth+"px");
		footerHTML.setHeight(headerHeight+"px");
		
		footerHTML.setWidth((widgetWidth-2)+"px");
	}
	
	private void setupResizeHandler() {
		resizeHandlerHTML = new HTML(){
			public void onBrowserEvent(Event event) {
				super.onBrowserEvent(event);
				switch (DOM.eventGetType(event)) {
				case Event.ONMOUSEDOWN:
					startResizingWidth = getInstanceItemsList().getOffsetWidth();
					startResizingHeight = getInstanceItemsList().getOffsetHeight();
					startResizingMouseX = DOM.eventGetClientX(event);
					startResizingMouseY = DOM.eventGetClientY(event);

					setupDraggingEP();
					break;
					
				default:
					break;
				}
			}
		};

		DOM.sinkEvents(resizeHandlerHTML.getElement(), Event.ONMOUSEDOWN);
		
		resizeHandlerHTML.setStyleName(STYLE__SELECT_BOX_RESIZE_HANDLER);
		resizeHandlerHTML.setWidth(12+"px");
		resizeHandlerHTML.setHeight(12+"px");
	}
	
	private void setupDropDownIcon() {
		dropDownIconHTML = new HTML();
		dropDownIconHTML.setWidth("18px");
		dropDownIconHTML.setHeight("17px");
		
		dropDownIconHTML.setStyleName(STYLE__SELECT_BOX_DROPDOWN_ICON);
		addDropDownIconListener();
	}
	
	
	private void addDropDownIconListener() {
		if (dropDownIconClickListener == null) {
			dropDownIconClickListener = new ClickListener() {
				public void onClick(Widget sender) {
//					Planner.log("klik");
					if (itemsPanelDisplayed) {
						//chowamy
						turnOffItemsPanel();
					} else {
						//pokazujemy
						turnOnItemsPanel();
						setViewOnFocus();
					}
				}
			};
			dropDownIconHTML.addClickListener(dropDownIconClickListener);
		}

	}
	
	private void removeDropDownIconListener() {
		if (dropDownIconClickListener != null) {
//			Planner.log("listener != null");
			dropDownIconHTML.removeClickListener(dropDownIconClickListener);
		}
	}
	
	
	private void setupDraggingEP() {
		if (draggingEP == null) {
			draggingEP = new EventPreview() {
				
				public boolean onEventPreview(Event event) {
					switch (DOM.eventGetType(event)) {
					
					case Event.ONMOUSEMOVE:
						if (!GUIUtil.eventOverWiget(itemsAP, event)) {
//							cursorOutOfItemsPanelWhileDragging = 1;
//							cursorOutOfItemsPanelWhileDraggingCopy = 1;
						} else {
//							if (cursorOutOfItemsPanelWhileDragging == 1) {
//								cursorOutOfItemsPanelWhileDragging = 2;
//								cursorOutOfItemsPanelWhileDraggingCopy = 2;
//							}
						}
						
						int widthGain = DOM.eventGetClientX(event) - startResizingMouseX;
						int newWidth = startResizingWidth + widthGain;

						int heightGain = DOM.eventGetClientY(event) - startResizingMouseY;
						int newHeight = startResizingHeight + heightGain;
						
						changeWidth(newWidth);
						changeHeight(newHeight);
						break;
					
						
					case Event.ONMOUSEUP:
						//obliczyc rozmiar
						//zmienic rozmiar
						DOM.removeEventPreview(draggingEP);
//						cursorOutOfItemsPanelWhileDragging = 0;
//						draggingInProgress = false;

						break;

					default:
						break;
					}
					return false;
				}
			};
		}


//		DOM.removeEventPreview(activeEP);
		DOM.addEventPreview(draggingEP);
//		draggingInProgress = true;
	}
	
	
	private void setupActiveEP() {
//		if (activeEP == null) {
//			activeEP = new EventPreview() {
//				public boolean onEventPreview(Event event) {
//					switch (DOM.eventGetType(event)) {
//					case Event.ONCLICK:
//						if (!GUIUtil.eventOverWiget(mainAP, event) && cursorOutOfItemsPanelWhileDraggingCopy != 0) {
//							//nie jest generowany w ff
//							WidgetsProject.log("TUTAJAAAAA ZAMYKAM");
//							cursorOutOfItemsPanelWhileDraggingCopy = 0;
//							
//							return false;
//						}
//						//break;
//					case Event.ONMOUSEUP:
//						WidgetsProject.log("cursorA " + cursorOutOfItemsPanelWhileDragging + ", " + draggingInProgress);
////						WidgetsProject.log("ONMOUSEUP w activeEP ZERUJE LICZNKI" + draggingInProgress );
//						break;
//					case Event.ONMOUSEDOWN:
//						WidgetsProject.log("DOWN " + cursorOutOfItemsPanelWhileDragging + ", " + draggingInProgress);
//						break;
//					default:
//						break;
//					}
//					return true;
//				}
//			};
//		}
//		DOM.addEventPreview(activeEP);
	}
	
	private void setupBordersHTML() {
		borderN.addStyleName(STYLE__SELECT_BOX_BORDER);
		borderN.addStyleName(STYLE__SELECT_BOX_BORDERN);
		//borderN.setWidth(widgetWidth+"px");
		
		borderS.addStyleName(STYLE__SELECT_BOX_BORDER);
		borderS.addStyleName(STYLE__SELECT_BOX_BORDERS);
		//borderS.setWidth(widgetWidth+"px");
		
		borderE.addStyleName(STYLE__SELECT_BOX_BORDER);
		borderE.addStyleName(STYLE__SELECT_BOX_BORDERE);
		//borderE.setHeight(widgetHeight+"px");
		
		borderW.addStyleName(STYLE__SELECT_BOX_BORDER);
		borderW.addStyleName(STYLE__SELECT_BOX_BORDERW);
		//borderW.setHeight(widgetHeight+"px");
	}
	
	private void setupItemsVP() {
		itemsVP.setStyleName(STYLE__SELECT_BOX_ITEMSLIST);
		
		//itemsAP.setBorderWidth(0);
	}
	
	private void setupItemsSP() {
		itemsSP.addStyleName(STYLE__ITEMS_SP);
		itemsSP.add(itemsVP);
		itemsSP.setWidth(widgetWidth+"px");
		itemsSP.setHeight((widgetHeight-headerHeight*2)+"px");
		DOM.setStyleAttribute(itemsSP.getElement(), "overflowX", "hidden");
	}
	
	private void setupMainAP() {
		itemsAP.setStyleName(STYLE__SELECT_BOX_ITEMSLIST);
		itemsAP.setWidth(widgetWidth+"px");
		itemsAP.setHeight(widgetHeight+"px");

		itemsAP.add(borderN);
		itemsAP.add(borderS);
		itemsAP.add(borderE);
		itemsAP.add(borderW);

		itemsAP.add(resizeHandlerHTML);
		
//		mainAP.add(headerHTML);
		itemsAP.add(footerHTML);
		
//		mainAP.add(itemsSP, 0, headerHeight);
		itemsAP.add(itemsSP, 0, 0);
	}
	
	
	private AbsolutePanel getInstanceItemsList() {
		return itemsAP;
	}
	
	private SelectBox getInstance() {
		return this;
	}


	
	/**
	 * Change width of panel with items.
	 * @param w
	 */
	private void changeWidth(int w) {
//		WidgetsProject.log("width: " + w);
		w = (w<10) ? 10:w;
		
		if (w<textBox.getOffsetWidth()) {
			w = textBox.getOffsetWidth();
		}
		
		itemsAP.setWidth(w + "px");
//		headerHTML.setWidth(w + "px");
		footerHTML.setWidth(w + "px");
		itemsSP.setWidth(w + "px");
		itemsVP.setWidth(w + "px");
		itemsAP.setWidgetPosition(borderE, w-1, 0);
	}
	
	private void changeHeight(int h) {
//		int minH = headerHTML.getOffsetHeight() + footerHTML.getOffsetHeight();
//		h = (h<minH) ? minH : h;
		int minH = footerHTML.getOffsetHeight();
		
//		if (h < headerHTML.getOffsetHeight() + footerHTML.getOffsetHeight() + itemHeight) {
//			h = headerHTML.getOffsetHeight() + footerHTML.getOffsetHeight() + itemHeight;
//		}
		
		if (h < itemHeight + footerHTML.getOffsetHeight()) {
			h = itemHeight + footerHTML.getOffsetHeight();
		}

		
		
//		int maxH = headerHTML.getOffsetHeight() + footerHTML.getOffsetHeight() + itemsVP.getOffsetHeight(); 
		int maxH = itemsVP.getOffsetHeight() + footerHTML.getOffsetHeight();
		if (h > maxH) h = maxH;
		
		itemsAP.setHeight(h + "px");
		itemsSP.setHeight( (h - minH) + "px" );
		
		
		itemsAP.setWidgetPosition(borderS, 0, h-1);
		itemsAP.setWidgetPosition(footerHTML, 0, h-headerHeight);
	}
	
	private HTML addItemHTML(String text, boolean selected) {
		final HTML html = new HTML(text);

		 
		html.setStyleName("item");
		html.setWidth("100%");
		
		if (selected) {
			html.addStyleName(STYLE_ITEMSLIST_SELECTED);
		}
		
		itemsVP.add(html);
		
		html.addMouseListener(new MouseListenerAdapter(){
			public void onMouseEnter(Widget sender) {
				super.onMouseEnter(sender);
				html.addStyleName(STYLE_ITEMSLIST_HOVER);
			}
			public void onMouseLeave(Widget sender) {
				super.onMouseLeave(sender);
				html.removeStyleName(STYLE_ITEMSLIST_HOVER);
			}
			public void onMouseDown(Widget sender, int x, int y) {
				super.onMouseDown(sender, x, y);
				VerticalPanel vp = (VerticalPanel)html.getParent();
				selectedItemindex = vp.getWidgetIndex(html);
				//Window.alert("wybrales pozycje " + index);
				textBox.setText(html.getText());
				fireOnChangeOnAllListeners();
				turnOffItemsPanel();
			}
		});
		
		
		if (selected) {
//			Planner.log("SelectBox.addItemHTML: " + "WYBRANO " + itemsVP.getWidgetCount());
			return html; 
		} else {
//			Planner.log("SelectBox.addItemHTML: " + "NIET WYBRANO");

			return null;
		}
	}
	
	private void setViewOnFocus(){
		textBox.addStyleName(STYLE_ONFOCUS);
		dropDownIconHTML.addStyleName(STYLE__SELECT_BOX_DROPDOWN_ICON_ON_FOCUS);
	}
	
	private void setViewOnLostFocus(){
		textBox.removeStyleName(STYLE_ONFOCUS);
		dropDownIconHTML.removeStyleName(STYLE__SELECT_BOX_DROPDOWN_ICON_ON_FOCUS);
	}

	
	private void turnOnItemsPanel() {
		HTML selectedHTML = null;

		
		for (int i = 0; i < items.size(); i++) {
			HTML addedHTML = addItemHTML((String)items.get(i), i == selectedItemindex); 
			if (i == selectedItemindex) {
				selectedHTML = addedHTML; 
			}
		}
		
		if (items.size()<=0) {
			addUnselectableItemHTML(noItemsLabel);
		}
		
//		if (itemsListWidth != -1) {
//			changeWidth(itemsListWidth);	
//		} else {
//			changeWidth(textBox.getOffsetWidth());
//		}
//		if (itemsListHeight != -1) {
//			changeHeight(itemsListHeight);
//		} else {
//			changeHeight(widgetHeight);
//		}
		
		PopupPanel pp = new PopupPanel(true, true);
		pp.addStyleName(STYLE__SELECT_BOX_ITEMSLIST_WRAPPER);
		pp.setWidget(itemsAP);
		pp.setPopupPosition(getInstance().getAbsoluteLeft(),
				getInstance().getAbsoluteTop()+getInstance().getOffsetHeight());
		pp.show();
		pp.addPopupListener(new PopupListener(){
			public void onPopupClosed(PopupPanel sender, boolean autoClosed) {
				
				turnOffItemsPanel();
				setViewOnLostFocus();
			}
		});
		
		
		itemsPanelDisplayed = true;
		
		//zmiana rozmiaru na standardowy tylko przy pierwszym uruchomieniu
		
		if (!itemsPanelDisplayedAtLeastOnce) {
			if (!itemsPanelWidthSet) {
				changeWidth(textBox.getOffsetWidth());	
			}
			
			
//			int newHeight = headerHTML.getOffsetHeight() + footerHTML.getOffsetHeight() + visibleItems*itemHeight;
			int newHeight = visibleItemsCount*itemHeight + footerHTML.getOffsetHeight();
			changeHeight(newHeight);
		} else {
			//GDY W WYNIKU USUNIECIA ELEMENTU ILOSC WSZSTYKICH JEST MNIEJSZA NIZ WYSOKOSC WYSWIETLANIA
			if (getVisibleItemsCount() > getItemCount()) {
				
				setVisibleItemsCount(getItemCount());
				int newHeight = visibleItemsCount*itemHeight + footerHTML.getOffsetHeight();
				changeHeight(newHeight);
				
			}
		}
		//setItemsPanelHeightImpl(itemsPanelHeight);
		
		
		itemsPanelDisplayedAtLeastOnce = true;
		setupActiveEP();
		
		//upewnienie sie, ze wybrany element jest widoczny od razu
		if (selectedHTML != null) {
			itemsSP.ensureVisible(selectedHTML);
		}
		
	}
	
	private void turnOffItemsPanel() {
//		draggingInProgress = false;
//		DOM.removeEventPreview(activeEP);
		//itemsPanelVP.removeFromParent();
		//itemsSP.removeFromParent();
		
		itemsVP.clear();
		PopupPanel pp = (PopupPanel)itemsAP.getParent();
		pp.hide();
		itemsAP.removeFromParent();
		
		itemsPanelDisplayed = false;
		//textBox.setFocus(true);
		//textBox.setSelectionRange(2, 4);
		//textBox.setFocus(false);
	}

	
	private void addUnselectableItemHTML(String text) {
		final HTML html = new HTML(text);

		html.setStyleName("unselectableItem");
		html.setWidth("100%");
		
		itemsVP.add(html);
	}

	public void addItem(String item) {
		addItem(item, item);
	}
	
	public void removeItem(int index) {
		items.remove(index);
		values.remove(index);
	}
	
	public void addItem(String item, String value) {
		//przy dodawaniu nowego elementu
		
//		Planner.log("SelectBox.addItem() selectedItemInd " + selectedItemindex);
		
//		if (selectedItemindex == -1 && items.size() == 0) {
//		if (items.size() == 0) {
//			textBox.setText(value);
//		}
		
		items.add(item);
		values.add(value);

		if (items.size() == 1) {
			setSelectedIndex(0);
		}
		
	}
	
	public void clear() {
		items.clear();
		values.clear();
		textBox.setText(noItemsLabel);
		selectedItemindex = -1;
		itemsPanelDisplayedAtLeastOnce = false;
	}
	
	public int getItemCount() {
		return items.size();
	}
	
	public String getItemText(int index) {
		return (String)items.get(index);
	}

	public String getValue(int index) {
		return (String)values.get(index);
	}
	
	/**
	 * Dziala tylko przed pierwszym kliknieciem na kontrolke.
	 * @param visibleItems
	 */
	public void setVisibleItemsCount(int visibleItems) {
		this.visibleItemsCount = visibleItems;
	}
	
	/**
	 * Dziala w kazdym momencie.
	 * @param visibleItems
	 */
	public void setHeightToDisplayItemsCount(int visibleItems) {
		this.visibleItemsCount = visibleItems; 
//		int newHeight = visibleItemsCount*itemHeight + footerHTML.getOffsetHeight();
//		Planner.log("SelectBox.setHeightToDisplayItemsCount: ASDFGH " + newHeight);
//		
//		changeHeight(newHeight);
	}
	
	public void setItemsPanelWidth(int width) {
		itemsPanelWidthSet = true;
		changeWidth(width);
	}
	
	//@Override
	public void setWidth(String width) {
		super.setWidth(width);
		mainAP.setWidth(width);
		textBox.setWidth(width);
	}
	
	public void setEnabled(boolean enabled) {
		textBox.setEnabled(enabled);
		if (enabled) {
			addDropDownIconListener();
			dropDownIconHTML.removeStyleName(STYLE__SELECT_BOX_DROPDOWN_ICON_DISABLED);
		} else {
			removeDropDownIconListener();
			dropDownIconHTML.addStyleName(STYLE__SELECT_BOX_DROPDOWN_ICON_DISABLED);
		}
	}
	
	public boolean isEnabled() {
		return textBox.isEnabled();
	}

	public void setNoItemsLabel(String noItemsLabel) {
		this.noItemsLabel = noItemsLabel;
	}
	
	public int getSelectedIndex() {
		return selectedItemindex;
	}
	
	
	public void addChangeListener(ChangeListener listener) {
		if (changeListeners == null) {
			changeListeners = new ChangeListenerCollection();
		}
		changeListeners.add(listener);
	}
	
	public void removeChangeListener(ChangeListener listener) {
		if (changeListeners != null) {
			changeListeners.remove(listener);
		}
	}
	
	private void fireOnChangeOnAllListeners() {
		if (changeListeners!= null) {
			for (int i = 0; i < changeListeners.size(); i++) {
				ChangeListener cl = (ChangeListener)changeListeners.get(i);
				cl.onChange(SelectBox.this);
			}
		}
		
	}
	
	public void setSelectedIndex(int index) {
		selectedItemindex = index;
//		listBox.setSelectedIndex(index);

		Object object = items.get(index);
		
		if (object != null) {
			String s = (String)object;
			textBox.setText(s);
		}
		
		
		
//		textBox.setText(value);
//		
//		items.add(item);
//		values.add(value);
	}

	public int getVisibleItemsCount() {
		return visibleItemsCount;
	};
	
}
